#define _GNU_SOURCE
#include "app_serial.h"
#include "log/log.h"
#include <stdlib.h>

SerialDevice *app_serial_init(char *filename)
{
    // 初始化一个设备
    Device *device = app_device_init(filename);
    if (!device)
    {
        log_error("app_serial_init error");
        goto DEVICE_INIT_FAIL;
    }
    // 在设备内存基础上扩展出一个串口内存设备
    SerialDevice *serial = realloc(device, sizeof(SerialDevice));
    if (!serial)
    {
        log_error("app_serial_init error");
        goto SERIAL_INIT_FAIL;
    }
    if (app_serial_setBraudRate(serial, BR_115200) != 0)
    {
        log_error("app_serial_setBraudRate error");
        // 得到首地址
        goto SERIAL_INIT_FAIL;
    }
    if (app_serial_setParity(serial, Parity_None) != 0)
    {
        log_error("app_serial_setParity error");
        // 得到首地址
        goto SERIAL_INIT_FAIL;
    }
    if (app_serial_setStopBits(serial, StopBits_1) != 0)
    {
        log_error("app_serial_setStopBits error");
        // 得到首地址
        goto SERIAL_INIT_FAIL;
    }
    // 让前面设置的所有属性生效
    tcflush(serial->super.fd, TCIOFLUSH);
    return serial;

SERIAL_INIT_FAIL:
    app_device_close(device);
DEVICE_INIT_FAIL:
    return NULL;
}
/**
 * 设置波特率
 */
int app_serial_setBraudRate(SerialDevice *serial, BraudRate braud_rate)
{
    serial->braud_rate = braud_rate;
    struct termios termios;
    // 获取串口属性
    if (tcgetattr(serial->super.fd, &termios) != 0)
    {
        log_error("tcgetattr error");
        return -1;
    }
    // 修改属性（波特率）
    // cfsetispeed(&termios, braud_rate);
    // cfsetospeed(&termios, braud_rate);
    cfsetspeed(&termios, braud_rate);
    // 设置串口属性(只有调用flash后 设置才会生效)
    if (tcsetattr(serial->super.fd, TCSANOW, &termios) != 0)
    {
        log_error("tcsetattr error");
        return -1;
    }
    return 0;
}
/**
 * 设置校验位
 */
int app_serial_setParity(SerialDevice *serial, Parity parity)
{
    serial->braud_rate = parity;
    struct termios termios;
    // 获取串口属性
    if (tcgetattr(serial->super.fd, &termios) != 0)
    {
        log_error("tcgetattr error");
        return -1;
    }
    // 修改属性（校验位）
    termios.c_cflag &= ~(PARENB | PARODD); // 清除校验位
    termios.c_cflag |= parity;             // 制定校验位

    // 设置串口属性(只有调用flash后 设置才会生效)
    if (tcsetattr(serial->super.fd, TCSANOW, &termios) != 0)
    {
        log_error("tcsetattr error");
        return -1;
    }
    return 0;
}
/**
 * 设置停止位
 */
int app_serial_setStopBits(SerialDevice *serial, Stopbites stop_bits)
{
    serial->braud_rate = stop_bits;
    struct termios termios;
    // 获取串口属性
    if (tcgetattr(serial->super.fd, &termios) != 0)
    {
        log_error("tcgetattr error");
        return -1;
    }
    // 修改属性（停止位）
    termios.c_cflag &= ~CSTOPB;
    termios.c_cflag |= stop_bits;
    // 设置串口属性(只有调用flash后 设置才会生效)
    if (tcsetattr(serial->super.fd, TCSANOW, &termios) != 0)
    {
        log_error("tcsetattr error");
        return -1;
    }
    return 0;
}
/**
 * 设置连接类型
 */
int app_serial_setConnectionType(SerialDevice *serial, ConnectionType conn_type)
{
    
    return 0;
}